package com.teamwings.modules.design.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.teamwings.common.constant.FormConstant;
import com.teamwings.common.exception.ResultException;
import com.teamwings.common.vo.Result;
import com.teamwings.modules.cate.entity.FormTableCate;
import com.teamwings.modules.code.entity.FormTableCode;
import com.teamwings.modules.code.service.IFormTableCodeService;
import com.teamwings.modules.design.entity.FormTableDesignTemplate;
import com.teamwings.modules.design.service.IDesignService;
import com.teamwings.modules.design.service.IDesignTemplateService;
import com.teamwings.modules.design.vo.FormVo;
import com.teamwings.modules.head.entity.FormTableHead;
import com.teamwings.modules.head.service.IFormTableHeadService;
import com.teamwings.util.FieldsLoopUtil;
import com.teamwings.util.VoUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Base64;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author admin
 * @since 2021-05-06
 */
@SuppressWarnings("DuplicatedCode")
@RestController
@Api(tags = "表单设计管理")
@RequestMapping("/form/design")
public class DesignController {

    @Autowired
    private IDesignService designService;

    @Autowired
    private IFormTableCodeService formTableCodeService;

    @Autowired
    private IFormTableHeadService formTableHeadService;

    @Autowired
    private IDesignTemplateService designTemplateService;

    /**
     * 分页查询
     */
    @ApiOperation(value = "获取design分页", notes = "获取design分页")
    @GetMapping(value = "/list")
    public Result<?> list(
            @RequestParam(value = "page", defaultValue = "1") Long page,
            @RequestParam(value = "pageSize", defaultValue = "20") Long pageSize,
            @RequestParam(value = "key", required = false) String key,
            @RequestParam(value = "cate_id", required = false) String cateId
    ) {
        IPage<FormVo> list = designService.page(page, pageSize, key, cateId);
        return Result.OK(list);
    }

    /**
     * 不做新增，新增放在 FormTableHeadServiceImpl.saveCode当中
     * 添加表单设计
     */
    // @Deprecated
    // @ApiOperation(value = "添加表单设计数据", notes = "添加表单设计数据")
    // @PostMapping(value = "/add")
    // public Result<?> add(@RequestBody String jsonForm, @RequestHeader("X-Remake") String tableRemarks) {
    //     designService.save(jsonForm, URLDecoder.decode(tableRemarks));
    //     return Result.OK("添加成功！");
    // }

    /**
     * 添加表单设计
     * FORM_HEAD_CODE缓存由 FormTableCodeServiceImpl清除
     */
    @ApiOperation(value = "修改表单设计数据", notes = "修改表单设计数据")
    @PutMapping(value = "/edit")
    @Caching(evict = {
            // @CacheEvict(value = {
            //         FormConstant.FORM_HEAD_HEAD,
            //         FormConstant.FORM_HEAD_COLUMN
            // }, key="#head.id", condition = "#head != null"), // #head 并非接收参数，head为null，存在报错id is null error
            @CacheEvict(value = FormConstant.FORM_HEAD_PAGING, key = "'*'")
    })
    public Result<?> edit(@RequestBody String jsonForm, @RequestHeader("X-Remake") String tableRemarks) {
        designService.edit(jsonForm, URLDecoder.decode(tableRemarks));
        return Result.OK("更新成功！");
    }

    /**
     * 根据formId(tableHeadId)查询最新一条form_table_code数据
     */
    @Cacheable(value = FormConstant.FORM_DESIGN_HEAD, key="#tableHeadId")
    @ApiOperation(value = "根据formId(tableHeadId)查询最新一条form_table_code数据", notes = "根据formId(tableHeadId)查询最新一条form_table_code数据")
    @GetMapping(value = "/getLastOne")
    public Result<?> getLastOne(@RequestParam(value = "tableHeadId") String tableHeadId) {
        FormTableHead head = formTableHeadService.getById(tableHeadId);
        if (head == null) {
            throw new ResultException("没有对应的表单设计");
        }

        Integer tableVersion = head.getTableVersion();
        if (tableVersion == null || tableVersion == 0) {
            throw new ResultException("当前表单是一个空表单");
        }

        FormTableCode code = formTableCodeService.getLatestOneByFormId(tableHeadId);
        String tableCode = code.getTableCode();
        //FormVo formVo = JSON.parseObject(tableCode, FormVo.class);n
        FormVo formVo = VoUtils.newFormVo(tableCode);
        return Result.OK("获取成功！", formVo);
    }

    /**
     * 根据formId(tableHeadId)或者和tableVersion查询一条form_table_code数据
     */
//    @Cacheable(value = FormConstant.FORM_DESIGN_HEAD, key="#tableHeadId"+"-"+"#tableVersion")
    @ApiOperation(value = "根据formId(tableHeadId)或者和tableVersion查询最新一条form_table_code数据",
        notes = "根据formId(tableHeadId)或者和tableVersion查询最新一条form_table_code数据")
    @GetMapping(value = "/view")
    public Result<?> view(@RequestParam(value = "tableHeadId") String tableHeadId,
                          @RequestParam(value = "tableVersion",required = false) Integer tableVersion
    ) {
        // 先查询当前表单是否有version
        FormTableHead head = formTableHeadService.getById(tableHeadId);
        if (head == null) {
            throw new ResultException("没有对应的表单设计");
        }
        //如果版本号为空，就使用当前的版本号
        if (tableVersion == null) {
            tableVersion = head.getTableVersion();
        }

        FormTableCode code = formTableCodeService.getByFormIdAndVersion(tableHeadId,tableVersion);
        code.setHead(head);
        // JSONObject jo = new JSONObject();
        // jo.put("code", code);

        // 添加使用者信息
        // LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        // String username = sysUser.getUsername();
        // JSONObject userJo = new JSONObject();
        // userJo.put("username", sysUser.getUsername());
        // userJo.put("realname", sysUser.getRealname());
        // jo.put("user", );

        //因需要修改备注，所以直接返回 code
        //String tableCode = code.getTableCode();
        //FormVo formVo = JSON.parseObject(tableCode, FormVo.class);
        //FormVo formVo = VoUtils.newFormVo(tableCode);
        // return Result.OK("获取成功！", jo);
        return Result.OK("获取成功！", code);
    }

    @ApiOperation(value = "根据formId查询当前的form_table_code使用的字段", notes = "")
    @GetMapping(value = "/fields")
    public Result<?> fields(@RequestParam(value = "tableHeadId") String tableHeadId) {
        // 先查询当前表单是否有version
        FormTableHead head = formTableHeadService.getById(tableHeadId);
        if (head == null) {
            throw new ResultException("没有对应的表单设计");
        }

        Integer tableVersion = head.getTableVersion();
        if (tableVersion == null || tableVersion == 0) {
            throw new ResultException("当前表单是一个空表单");
        }

        FormTableCode code = formTableCodeService.getLatestOneByFormId(tableHeadId);
        String tableCode = code.getTableCode();
        //FormVo formVo = JSON.parseObject(tableCode, FormVo.class);
        FormVo formVo = VoUtils.newFormVo(tableCode);

        JSONArray ja = new JSONArray();

        // 填充
        FieldsLoopUtil.loop(formVo.getList(), formComponent -> {
            JSONObject jo = new JSONObject();
            jo.put("key", formComponent.getModel());
            jo.put("value", formComponent.getLabel());
            ja.add(jo);
        });
        return Result.OK(ja);
    }

    /**
     * 表单复制
     */
    @ApiOperation(value = "表单复制", notes = "表单复制")
    @PostMapping(value = "/cloneForm")
    public Result<?> cloneForm(
            @RequestParam(value = "formId") String formId,
            @RequestParam(value = "newTableName") String newTableName) {
        designService.cloneForm(formId, newTableName);
        return Result.OK("表单复制成功！");
    }


    /**
     * 保存为模板
     */
    @ApiOperation(value = "保存为模板", notes = "保存为模板")
    @PostMapping(value = "/saveWithTemplate")
    public Result<?> saveWithTemplate(
            @RequestBody String jsonForm,
            @RequestHeader("X-Name") String name,
            @RequestHeader(value = "X-Force-Save", required = false, defaultValue = "false") Boolean forceSave
    ) {
        designService.saveWithTemplate(jsonForm, URLDecoder.decode(name), forceSave);
        return Result.OK("保存模板成功！");
    }


    /**
     * 获取模板列表
     */
    @ApiOperation(value = "获取模板列表", notes = "获取模板列表")
    @GetMapping(value = "/templateList")
    public Result<?> templateList(
            @RequestParam(value = "page", defaultValue = "1") Long page,
            @RequestParam(value = "pageSize", defaultValue = "20") Long pageSize,
            @RequestParam(value = "name", required = false) String name
    ) {
        Page<FormTableDesignTemplate> designTemplatePage = new Page<>(page, pageSize);
        LambdaQueryWrapper<FormTableDesignTemplate> queryWrapper = new LambdaQueryWrapper<>();
        // 只查询id, updateTime, name字段
        queryWrapper.select(
                FormTableDesignTemplate::getId,
                FormTableDesignTemplate::getUpdateTime,
                FormTableDesignTemplate::getName
        );

        if (StringUtils.isNotEmpty(name)) {
            queryWrapper.like(FormTableDesignTemplate::getName, name);
        }

        IPage<FormTableDesignTemplate> list = designTemplateService.page(designTemplatePage, queryWrapper);
        return Result.OK(list);
    }

    /**
     * 获取一条模板数据
     */
    @ApiOperation(value = "获取一条模板数据", notes = "获取一条模板数据")
    @GetMapping(value = "/queryTemplateById")
    public Result<?> queryTemplateById(@RequestParam(name = "id", required = true) String id) {
        FormTableDesignTemplate entity = designTemplateService.getById(id);
        return Result.OK("获取数据成功！", entity);
    }

    @ApiOperation(value = "根据id删除模板数据", notes = "根据id删除模板数据")
    @DeleteMapping(value = "/removeTemplateById")
    public Result<?> removeTemplateById(@RequestParam(value = "id", required = false) String id) {
        designTemplateService.removeById(id);
        return Result.OK("添加成功！");
    }

}
